#include "app_mqtt.h"
#include "log/log.h"
#include <MQTTClient.h>
#include <string.h>

static MQTTClient client;
static MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
static int (*recv_callback)(char *json) = NULL;
static MQTTClient_message pubmsg = MQTTClient_message_initializer;

// 发送消息完成的回调函数
static void delivered(void *context, MQTTClient_deliveryToken dt)
{
    log_debug("发送消息完成");
}

// 接收到消息的回调函数
// 消息的返回值： 1表示消息处理成功，0表示消息处理失败
static int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message)
{
    int result = 0; // 默认没有成功处理
    if (recv_callback) {
        result = recv_callback((char *)message->payload)==0 ? 1 : 0;
    }

    // 释放内存
    MQTTClient_freeMessage(&message);
    MQTTClient_free(topicName);

    return result;
}

// 连接断开的回调函数
static void connlost(void *context, char *cause)
{
    log_error("连接断开，原因：%s", cause);
}


int app_mqtt_init(void)
{
    // 创建客户端
    if (MQTTClient_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL) !=MQTTCLIENT_SUCCESS) {
        log_error("创建MQTT客户端失败");
        return -1;
    }

    // 设置回调函数
    if(MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered) != MQTTCLIENT_SUCCESS) {
        log_error("设置MQTT回调函数失败");
        MQTTClient_destroy(&client);
        return -1;
    }
    // 连接服务
    if (MQTTClient_connect(client, &conn_opts) != MQTTCLIENT_SUCCESS) {
        log_error("连接MQTT服务失败");
        MQTTClient_destroy(&client);
        return -1;
    }

    // 订阅主题
    if (MQTTClient_subscribe(client, TOPIC_RTG, QOS) != MQTTCLIENT_SUCCESS) {
        log_error("订阅主题失败");
        MQTTClient_disconnect(client, TIMEOUT);
        MQTTClient_destroy(&client);

        return -1;
    }
    log_debug("MQTT初始化成功");

    return 0;
}

void app_mqtt_close(void)
{
    MQTTClient_unsubscribe(client, TOPIC_RTG);
    MQTTClient_disconnect(client, TIMEOUT);
    MQTTClient_destroy(&client);
}

int app_mqtt_send(char *json)
{
    pubmsg.payload = json;
    pubmsg.payloadlen = strlen(json) + 1; // 需要发送结束符
    pubmsg.qos = QOS;

    if (MQTTClient_publishMessage(client, TOPIC_GTR, &pubmsg, NULL) != MQTTCLIENT_SUCCESS) {
        log_error("发送消息失败");
        return -1;
    }

    return 0;
}

void app_mqtt_registerRecvCallback(int (*callback)(char *json))
{
    recv_callback = callback;
}
